// $ANTLR 3.1.2 AmFm.g 2009-05-11 14:39:33

/*
 * Copyright 2009, Team Mondegreen:
 * Brian Hsieh - bh2181@columbia.edu
 * Eugene Yao - eyy2102@columbia.edu
 * Jake Amonette - jaa2149@columbia.edu
 * Tal Giat - tg2235@colubia.edu
 * 
 * This file is part of AMFM (A Minimal Fractal Music Language), a language created for
 * fractal music as part of the Programming Languages and Translator class at Columbia university.
 *
 * For more details go to: http://code.google.com/p/amfm/
 * 
 * AMFM is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * at your option any later version.
 * 
 * AMFM is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with AMFM.  If not, see <http://www.gnu.org/licenses/>. 
 */ 
package org.mondegreen.amfm.compiler;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;


import org.antlr.runtime.tree.*;

/**
 * Parser for AMFM programs outputs AST.
 *
 * @author talgiat
 */
@SuppressWarnings("all")
public class AmFmParser extends Parser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "PROGRAM", "DEF", "NOTEUNIT", "NOTE", "ID", "INSTRUMENT", "REST", "FRACTION", "VOLUME_LEVELS_MINUS_F", "NOTELETTERS_WITH_ACCIDENTAL_MINUS_F", "ACCIDENTAL", "ONE_TO_NINE", "START", "PLAY", "SS_PITCH", "SS_VOLUME", "SS_RHYTHM", "SS_PITCH_VOLUME", "SS_PITCH_RHYTHM", "SS_RHYTHM_VOLUME", "SS_ALL", "BOOLEAN", "TEN_AND_UP", "COMMENT", "WS", "'seed'", "'{'", "';'", "'}'", "','", "'F'", "'('", "')'"
    };
    public static final int ONE_TO_NINE=15;
    public static final int SS_RHYTHM=20;
    public static final int SS_PITCH=18;
    public static final int T__29=29;
    public static final int DEF=5;
    public static final int REST=10;
    public static final int SS_ALL=24;
    public static final int ACCIDENTAL=14;
    public static final int SS_RHYTHM_VOLUME=23;
    public static final int SS_PITCH_VOLUME=21;
    public static final int ID=8;
    public static final int INSTRUMENT=9;
    public static final int TEN_AND_UP=26;
    public static final int NOTELETTERS_WITH_ACCIDENTAL_MINUS_F=13;
    public static final int EOF=-1;
    public static final int NOTEUNIT=6;
    public static final int SS_VOLUME=19;
    public static final int SS_PITCH_RHYTHM=22;
    public static final int T__30=30;
    public static final int T__31=31;
    public static final int T__32=32;
    public static final int WS=28;
    public static final int BOOLEAN=25;
    public static final int T__33=33;
    public static final int T__34=34;
    public static final int T__35=35;
    public static final int T__36=36;
    public static final int NOTE=7;
    public static final int START=16;
    public static final int PROGRAM=4;
    public static final int VOLUME_LEVELS_MINUS_F=12;
    public static final int COMMENT=27;
    public static final int FRACTION=11;
    public static final int PLAY=17;

    // delegates
    // delegators


        public AmFmParser(TokenStream input) {
            this(input, new RecognizerSharedState());
        }
        public AmFmParser(TokenStream input, RecognizerSharedState state) {
            super(input, state);
             
        }
        
    protected TreeAdaptor adaptor = new CommonTreeAdaptor();

    public void setTreeAdaptor(TreeAdaptor adaptor) {
        this.adaptor = adaptor;
    }
    public TreeAdaptor getTreeAdaptor() {
        return adaptor;
    }

    public String[] getTokenNames() { return AmFmParser.tokenNames; }
    public String getGrammarFileName() { return "AmFm.g"; }


    /** The maximal number of function calls in the start function (due to midi 16 channels limitation) */
    private static final int MAX_NUM_OF_FUNCTION_CALLS = 16;

    /** All used (referenced) seeds */ 
    private Set<String> usedSeeds = new HashSet<String>();

    /** The number of functions actually called in the program */
    private int numOfFunctionCalls = 0;

    /**
     * A flag that indicated did we start at the program rule so we won't do semantic validation 
     * check in rules if we didn't (so we can test grammar rules independently)
     */
    private boolean startedFromProgramRule = false;

    /** List of all seeds names (i.e. simple symbol table) */
    private Map<String,Boolean> definedSeeds = new HashMap<String,Boolean>();

    /** An error manager to register all compilation errors to */
    private AmFmErrorManager errorManager;

    /** Flag for marking rest only seeds (invalid)*/
    private boolean seedOnlyRests; 

    /**
     * Sets the error manager this must be called before parsing or a NullPointerException will be throw in case of
     * semantic error because the code will try to add the error message to the manager. 
     * @param errorManager the compilation error manager 
     */
    public void setErrorManager(AmFmErrorManager errorManager) {
      this.errorManager = errorManager;
    }

    public Set<String> getUsedSeeds() { 
      return usedSeeds; 
    }

    /**
     * Overriding antlr's method so we can redirect (and register) its error messages to AmFmErrorManager 
     * @param msg the parsing error message to capture
     */
    public void emitErrorMessage(String msg) {
      errorManager.addError(AmFmErrorCode.ANTLR_ERROR, msg);
    }



    public static class program_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "program"
    // AmFm.g:151:1: program : ( seed )+ start_func -> ^( PROGRAM ( seed )+ start_func ) ;
    public final AmFmParser.program_return program() throws RecognitionException {
        AmFmParser.program_return retval = new AmFmParser.program_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        AmFmParser.seed_return seed1 = null;

        AmFmParser.start_func_return start_func2 = null;


        RewriteRuleSubtreeStream stream_seed=new RewriteRuleSubtreeStream(adaptor,"rule seed");
        RewriteRuleSubtreeStream stream_start_func=new RewriteRuleSubtreeStream(adaptor,"rule start_func");

        // Turn on flag to indicate we parse a full program 
        startedFromProgramRule = true;

        try {
            // AmFm.g:156:7: ( ( seed )+ start_func -> ^( PROGRAM ( seed )+ start_func ) )
            // AmFm.g:156:9: ( seed )+ start_func
            {
            // AmFm.g:156:9: ( seed )+
            int cnt1=0;
            loop1:
            do {
                int alt1=2;
                int LA1_0 = input.LA(1);

                if ( (LA1_0==29) ) {
                    alt1=1;
                }


                switch (alt1) {
            	case 1 :
            	    // AmFm.g:156:9: seed
            	    {
            	    pushFollow(FOLLOW_seed_in_program85);
            	    seed1=seed();

            	    state._fsp--;

            	    stream_seed.add(seed1.getTree());

            	    }
            	    break;

            	default :
            	    if ( cnt1 >= 1 ) break loop1;
                        EarlyExitException eee =
                            new EarlyExitException(1, input);
                        throw eee;
                }
                cnt1++;
            } while (true);

            pushFollow(FOLLOW_start_func_in_program88);
            start_func2=start_func();

            state._fsp--;

            stream_start_func.add(start_func2.getTree());

                    if (numOfFunctionCalls > MAX_NUM_OF_FUNCTION_CALLS) {
                      errorManager.addError(AmFmErrorCode.TOO_MANY_FUNCTION_CALLS, MAX_NUM_OF_FUNCTION_CALLS, numOfFunctionCalls);
                    }
                  


            // AST REWRITE
            // elements: start_func, seed
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 162:7: -> ^( PROGRAM ( seed )+ start_func )
            {
                // AmFm.g:162:10: ^( PROGRAM ( seed )+ start_func )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(PROGRAM, "PROGRAM"), root_1);

                if ( !(stream_seed.hasNext()) ) {
                    throw new RewriteEarlyExitException();
                }
                while ( stream_seed.hasNext() ) {
                    adaptor.addChild(root_1, stream_seed.nextTree());

                }
                stream_seed.reset();
                adaptor.addChild(root_1, stream_start_func.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;
            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "program"

    public static class seed_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "seed"
    // AmFm.g:165:1: seed : 'seed' ID '{' INSTRUMENT ';' ( note_unit )+ '}' -> ^( ID INSTRUMENT ( note_unit )+ ) ;
    public final AmFmParser.seed_return seed() throws RecognitionException {
        AmFmParser.seed_return retval = new AmFmParser.seed_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token string_literal3=null;
        Token ID4=null;
        Token char_literal5=null;
        Token INSTRUMENT6=null;
        Token char_literal7=null;
        Token char_literal9=null;
        AmFmParser.note_unit_return note_unit8 = null;


        Object string_literal3_tree=null;
        Object ID4_tree=null;
        Object char_literal5_tree=null;
        Object INSTRUMENT6_tree=null;
        Object char_literal7_tree=null;
        Object char_literal9_tree=null;
        RewriteRuleTokenStream stream_30=new RewriteRuleTokenStream(adaptor,"token 30");
        RewriteRuleTokenStream stream_32=new RewriteRuleTokenStream(adaptor,"token 32");
        RewriteRuleTokenStream stream_31=new RewriteRuleTokenStream(adaptor,"token 31");
        RewriteRuleTokenStream stream_ID=new RewriteRuleTokenStream(adaptor,"token ID");
        RewriteRuleTokenStream stream_INSTRUMENT=new RewriteRuleTokenStream(adaptor,"token INSTRUMENT");
        RewriteRuleTokenStream stream_29=new RewriteRuleTokenStream(adaptor,"token 29");
        RewriteRuleSubtreeStream stream_note_unit=new RewriteRuleSubtreeStream(adaptor,"rule note_unit");

        // Start of the seed we assume it only rests till proven otherwise
        seedOnlyRests = true;

        try {
            // AmFm.g:170:1: ( 'seed' ID '{' INSTRUMENT ';' ( note_unit )+ '}' -> ^( ID INSTRUMENT ( note_unit )+ ) )
            // AmFm.g:170:3: 'seed' ID '{' INSTRUMENT ';' ( note_unit )+ '}'
            {
            string_literal3=(Token)match(input,29,FOLLOW_29_in_seed130);  
            stream_29.add(string_literal3);

            ID4=(Token)match(input,ID,FOLLOW_ID_in_seed132);  
            stream_ID.add(ID4);

            char_literal5=(Token)match(input,30,FOLLOW_30_in_seed134);  
            stream_30.add(char_literal5);

            INSTRUMENT6=(Token)match(input,INSTRUMENT,FOLLOW_INSTRUMENT_in_seed136);  
            stream_INSTRUMENT.add(INSTRUMENT6);

            char_literal7=(Token)match(input,31,FOLLOW_31_in_seed138);  
            stream_31.add(char_literal7);

            // AmFm.g:170:32: ( note_unit )+
            int cnt2=0;
            loop2:
            do {
                int alt2=2;
                int LA2_0 = input.LA(1);

                if ( (LA2_0==REST||LA2_0==NOTELETTERS_WITH_ACCIDENTAL_MINUS_F||LA2_0==34) ) {
                    alt2=1;
                }


                switch (alt2) {
            	case 1 :
            	    // AmFm.g:170:32: note_unit
            	    {
            	    pushFollow(FOLLOW_note_unit_in_seed140);
            	    note_unit8=note_unit();

            	    state._fsp--;

            	    stream_note_unit.add(note_unit8.getTree());

            	    }
            	    break;

            	default :
            	    if ( cnt2 >= 1 ) break loop2;
                        EarlyExitException eee =
                            new EarlyExitException(2, input);
                        throw eee;
                }
                cnt2++;
            } while (true);

            char_literal9=(Token)match(input,32,FOLLOW_32_in_seed143);  
            stream_32.add(char_literal9);

             
                      if (startedFromProgramRule) { // Do validation only if we parse a whole program
            	          if (definedSeeds.get((ID4!=null?ID4.getText():null)) != null) { // Seed is defined twice
            	            errorManager.addError(AmFmErrorCode.REDIFINED_SEED, (ID4!=null?ID4.getLine():0), (ID4!=null?ID4.getText():null));
            	          } else { // Seed is ok - add its name to seeds lookup table
            	            definedSeeds.put((ID4!=null?ID4.getText():null),seedOnlyRests);
            	          }
                      }
                    


            // AST REWRITE
            // elements: ID, INSTRUMENT, note_unit
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 180:9: -> ^( ID INSTRUMENT ( note_unit )+ )
            {
                // AmFm.g:180:12: ^( ID INSTRUMENT ( note_unit )+ )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_ID.nextNode(), root_1);

                adaptor.addChild(root_1, stream_INSTRUMENT.nextNode());
                if ( !(stream_note_unit.hasNext()) ) {
                    throw new RewriteEarlyExitException();
                }
                while ( stream_note_unit.hasNext() ) {
                    adaptor.addChild(root_1, stream_note_unit.nextTree());

                }
                stream_note_unit.reset();

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;
            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "seed"

    public static class note_unit_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "note_unit"
    // AmFm.g:181:1: note_unit : ( note ( ',' duration ( ',' volume )? )? ';' -> ^( NOTEUNIT ^( NOTE note ) ( duration ( volume )? )? ) | REST ( ',' duration )? ';' -> ^( NOTEUNIT REST ( duration )? ) );
    public final AmFmParser.note_unit_return note_unit() throws RecognitionException {
        AmFmParser.note_unit_return retval = new AmFmParser.note_unit_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token char_literal11=null;
        Token char_literal13=null;
        Token char_literal15=null;
        Token REST16=null;
        Token char_literal17=null;
        Token char_literal19=null;
        AmFmParser.note_return note10 = null;

        AmFmParser.duration_return duration12 = null;

        AmFmParser.volume_return volume14 = null;

        AmFmParser.duration_return duration18 = null;


        Object char_literal11_tree=null;
        Object char_literal13_tree=null;
        Object char_literal15_tree=null;
        Object REST16_tree=null;
        Object char_literal17_tree=null;
        Object char_literal19_tree=null;
        RewriteRuleTokenStream stream_31=new RewriteRuleTokenStream(adaptor,"token 31");
        RewriteRuleTokenStream stream_33=new RewriteRuleTokenStream(adaptor,"token 33");
        RewriteRuleTokenStream stream_REST=new RewriteRuleTokenStream(adaptor,"token REST");
        RewriteRuleSubtreeStream stream_duration=new RewriteRuleSubtreeStream(adaptor,"rule duration");
        RewriteRuleSubtreeStream stream_volume=new RewriteRuleSubtreeStream(adaptor,"rule volume");
        RewriteRuleSubtreeStream stream_note=new RewriteRuleSubtreeStream(adaptor,"rule note");
        try {
            // AmFm.g:181:11: ( note ( ',' duration ( ',' volume )? )? ';' -> ^( NOTEUNIT ^( NOTE note ) ( duration ( volume )? )? ) | REST ( ',' duration )? ';' -> ^( NOTEUNIT REST ( duration )? ) )
            int alt6=2;
            int LA6_0 = input.LA(1);

            if ( (LA6_0==NOTELETTERS_WITH_ACCIDENTAL_MINUS_F||LA6_0==34) ) {
                alt6=1;
            }
            else if ( (LA6_0==REST) ) {
                alt6=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 6, 0, input);

                throw nvae;
            }
            switch (alt6) {
                case 1 :
                    // AmFm.g:181:13: note ( ',' duration ( ',' volume )? )? ';'
                    {
                    pushFollow(FOLLOW_note_in_note_unit182);
                    note10=note();

                    state._fsp--;

                    stream_note.add(note10.getTree());
                    // AmFm.g:181:19: ( ',' duration ( ',' volume )? )?
                    int alt4=2;
                    int LA4_0 = input.LA(1);

                    if ( (LA4_0==33) ) {
                        alt4=1;
                    }
                    switch (alt4) {
                        case 1 :
                            // AmFm.g:181:21: ',' duration ( ',' volume )?
                            {
                            char_literal11=(Token)match(input,33,FOLLOW_33_in_note_unit187);  
                            stream_33.add(char_literal11);

                            pushFollow(FOLLOW_duration_in_note_unit189);
                            duration12=duration();

                            state._fsp--;

                            stream_duration.add(duration12.getTree());
                            // AmFm.g:181:34: ( ',' volume )?
                            int alt3=2;
                            int LA3_0 = input.LA(1);

                            if ( (LA3_0==33) ) {
                                alt3=1;
                            }
                            switch (alt3) {
                                case 1 :
                                    // AmFm.g:181:36: ',' volume
                                    {
                                    char_literal13=(Token)match(input,33,FOLLOW_33_in_note_unit193);  
                                    stream_33.add(char_literal13);

                                    pushFollow(FOLLOW_volume_in_note_unit195);
                                    volume14=volume();

                                    state._fsp--;

                                    stream_volume.add(volume14.getTree());

                                    }
                                    break;

                            }


                            }
                            break;

                    }

                    char_literal15=(Token)match(input,31,FOLLOW_31_in_note_unit202);  
                    stream_31.add(char_literal15);

                     seedOnlyRests = false; 


                    // AST REWRITE
                    // elements: volume, note, duration
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (Object)adaptor.nil();
                    // 183:11: -> ^( NOTEUNIT ^( NOTE note ) ( duration ( volume )? )? )
                    {
                        // AmFm.g:183:14: ^( NOTEUNIT ^( NOTE note ) ( duration ( volume )? )? )
                        {
                        Object root_1 = (Object)adaptor.nil();
                        root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(NOTEUNIT, "NOTEUNIT"), root_1);

                        // AmFm.g:183:25: ^( NOTE note )
                        {
                        Object root_2 = (Object)adaptor.nil();
                        root_2 = (Object)adaptor.becomeRoot((Object)adaptor.create(NOTE, "NOTE"), root_2);

                        adaptor.addChild(root_2, stream_note.nextTree());

                        adaptor.addChild(root_1, root_2);
                        }
                        // AmFm.g:183:38: ( duration ( volume )? )?
                        if ( stream_volume.hasNext()||stream_duration.hasNext() ) {
                            adaptor.addChild(root_1, stream_duration.nextTree());
                            // AmFm.g:183:48: ( volume )?
                            if ( stream_volume.hasNext() ) {
                                adaptor.addChild(root_1, stream_volume.nextTree());

                            }
                            stream_volume.reset();

                        }
                        stream_volume.reset();
                        stream_duration.reset();

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;
                    }
                    break;
                case 2 :
                    // AmFm.g:184:13: REST ( ',' duration )? ';'
                    {
                    REST16=(Token)match(input,REST,FOLLOW_REST_in_note_unit260);  
                    stream_REST.add(REST16);

                    // AmFm.g:184:18: ( ',' duration )?
                    int alt5=2;
                    int LA5_0 = input.LA(1);

                    if ( (LA5_0==33) ) {
                        alt5=1;
                    }
                    switch (alt5) {
                        case 1 :
                            // AmFm.g:184:20: ',' duration
                            {
                            char_literal17=(Token)match(input,33,FOLLOW_33_in_note_unit264);  
                            stream_33.add(char_literal17);

                            pushFollow(FOLLOW_duration_in_note_unit266);
                            duration18=duration();

                            state._fsp--;

                            stream_duration.add(duration18.getTree());

                            }
                            break;

                    }

                    char_literal19=(Token)match(input,31,FOLLOW_31_in_note_unit270);  
                    stream_31.add(char_literal19);



                    // AST REWRITE
                    // elements: duration, REST
                    // token labels: 
                    // rule labels: retval
                    // token list labels: 
                    // rule list labels: 
                    // wildcard labels: 
                    retval.tree = root_0;
                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

                    root_0 = (Object)adaptor.nil();
                    // 184:39: -> ^( NOTEUNIT REST ( duration )? )
                    {
                        // AmFm.g:184:42: ^( NOTEUNIT REST ( duration )? )
                        {
                        Object root_1 = (Object)adaptor.nil();
                        root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(NOTEUNIT, "NOTEUNIT"), root_1);

                        adaptor.addChild(root_1, stream_REST.nextNode());
                        // AmFm.g:184:58: ( duration )?
                        if ( stream_duration.hasNext() ) {
                            adaptor.addChild(root_1, stream_duration.nextTree());

                        }
                        stream_duration.reset();

                        adaptor.addChild(root_0, root_1);
                        }

                    }

                    retval.tree = root_0;
                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "note_unit"

    public static class duration_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "duration"
    // AmFm.g:186:1: duration : ( FRACTION | number );
    public final AmFmParser.duration_return duration() throws RecognitionException {
        AmFmParser.duration_return retval = new AmFmParser.duration_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token FRACTION20=null;
        AmFmParser.number_return number21 = null;


        Object FRACTION20_tree=null;

        try {
            // AmFm.g:186:9: ( FRACTION | number )
            int alt7=2;
            int LA7_0 = input.LA(1);

            if ( (LA7_0==FRACTION) ) {
                alt7=1;
            }
            else if ( (LA7_0==ONE_TO_NINE||LA7_0==TEN_AND_UP) ) {
                alt7=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 7, 0, input);

                throw nvae;
            }
            switch (alt7) {
                case 1 :
                    // AmFm.g:186:11: FRACTION
                    {
                    root_0 = (Object)adaptor.nil();

                    FRACTION20=(Token)match(input,FRACTION,FOLLOW_FRACTION_in_duration299); 
                    FRACTION20_tree = (Object)adaptor.create(FRACTION20);
                    adaptor.addChild(root_0, FRACTION20_tree);


                    }
                    break;
                case 2 :
                    // AmFm.g:186:22: number
                    {
                    root_0 = (Object)adaptor.nil();

                    pushFollow(FOLLOW_number_in_duration303);
                    number21=number();

                    state._fsp--;

                    adaptor.addChild(root_0, number21.getTree());

                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "duration"

    public static class volume_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "volume"
    // AmFm.g:187:1: volume : ( VOLUME_LEVELS_MINUS_F | 'F' );
    public final AmFmParser.volume_return volume() throws RecognitionException {
        AmFmParser.volume_return retval = new AmFmParser.volume_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token set22=null;

        Object set22_tree=null;

        try {
            // AmFm.g:187:9: ( VOLUME_LEVELS_MINUS_F | 'F' )
            // AmFm.g:
            {
            root_0 = (Object)adaptor.nil();

            set22=(Token)input.LT(1);
            if ( input.LA(1)==VOLUME_LEVELS_MINUS_F||input.LA(1)==34 ) {
                input.consume();
                adaptor.addChild(root_0, (Object)adaptor.create(set22));
                state.errorRecovery=false;
            }
            else {
                MismatchedSetException mse = new MismatchedSetException(null,input);
                throw mse;
            }


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "volume"

    public static class note_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "note"
    // AmFm.g:188:1: note : note_letter ( octave )? ;
    public final AmFmParser.note_return note() throws RecognitionException {
        AmFmParser.note_return retval = new AmFmParser.note_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        AmFmParser.note_letter_return note_letter23 = null;

        AmFmParser.octave_return octave24 = null;



        try {
            // AmFm.g:188:6: ( note_letter ( octave )? )
            // AmFm.g:188:9: note_letter ( octave )?
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_note_letter_in_note323);
            note_letter23=note_letter();

            state._fsp--;

            adaptor.addChild(root_0, note_letter23.getTree());
            // AmFm.g:188:21: ( octave )?
            int alt8=2;
            int LA8_0 = input.LA(1);

            if ( (LA8_0==ONE_TO_NINE) ) {
                alt8=1;
            }
            switch (alt8) {
                case 1 :
                    // AmFm.g:188:21: octave
                    {
                    pushFollow(FOLLOW_octave_in_note325);
                    octave24=octave();

                    state._fsp--;

                    adaptor.addChild(root_0, octave24.getTree());

                    }
                    break;

            }


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "note"

    public static class note_letter_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "note_letter"
    // AmFm.g:189:1: note_letter : ( NOTELETTERS_WITH_ACCIDENTAL_MINUS_F | 'F' ( ACCIDENTAL )? );
    public final AmFmParser.note_letter_return note_letter() throws RecognitionException {
        AmFmParser.note_letter_return retval = new AmFmParser.note_letter_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25=null;
        Token char_literal26=null;
        Token ACCIDENTAL27=null;

        Object NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25_tree=null;
        Object char_literal26_tree=null;
        Object ACCIDENTAL27_tree=null;

        try {
            // AmFm.g:189:12: ( NOTELETTERS_WITH_ACCIDENTAL_MINUS_F | 'F' ( ACCIDENTAL )? )
            int alt10=2;
            int LA10_0 = input.LA(1);

            if ( (LA10_0==NOTELETTERS_WITH_ACCIDENTAL_MINUS_F) ) {
                alt10=1;
            }
            else if ( (LA10_0==34) ) {
                alt10=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 10, 0, input);

                throw nvae;
            }
            switch (alt10) {
                case 1 :
                    // AmFm.g:189:14: NOTELETTERS_WITH_ACCIDENTAL_MINUS_F
                    {
                    root_0 = (Object)adaptor.nil();

                    NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25=(Token)match(input,NOTELETTERS_WITH_ACCIDENTAL_MINUS_F,FOLLOW_NOTELETTERS_WITH_ACCIDENTAL_MINUS_F_in_note_letter334); 
                    NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25_tree = (Object)adaptor.create(NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25);
                    adaptor.addChild(root_0, NOTELETTERS_WITH_ACCIDENTAL_MINUS_F25_tree);


                    }
                    break;
                case 2 :
                    // AmFm.g:189:52: 'F' ( ACCIDENTAL )?
                    {
                    root_0 = (Object)adaptor.nil();

                    char_literal26=(Token)match(input,34,FOLLOW_34_in_note_letter338); 
                    char_literal26_tree = (Object)adaptor.create(char_literal26);
                    adaptor.addChild(root_0, char_literal26_tree);

                    // AmFm.g:189:55: ( ACCIDENTAL )?
                    int alt9=2;
                    int LA9_0 = input.LA(1);

                    if ( (LA9_0==ACCIDENTAL) ) {
                        alt9=1;
                    }
                    switch (alt9) {
                        case 1 :
                            // AmFm.g:189:55: ACCIDENTAL
                            {
                            ACCIDENTAL27=(Token)match(input,ACCIDENTAL,FOLLOW_ACCIDENTAL_in_note_letter339); 
                            ACCIDENTAL27_tree = (Object)adaptor.create(ACCIDENTAL27);
                            adaptor.addChild(root_0, ACCIDENTAL27_tree);


                            }
                            break;

                    }


                    }
                    break;

            }
            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "note_letter"

    public static class octave_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "octave"
    // AmFm.g:190:1: octave : ONE_TO_NINE ;
    public final AmFmParser.octave_return octave() throws RecognitionException {
        AmFmParser.octave_return retval = new AmFmParser.octave_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token ONE_TO_NINE28=null;

        Object ONE_TO_NINE28_tree=null;

        try {
            // AmFm.g:190:7: ( ONE_TO_NINE )
            // AmFm.g:190:9: ONE_TO_NINE
            {
            root_0 = (Object)adaptor.nil();

            ONE_TO_NINE28=(Token)match(input,ONE_TO_NINE,FOLLOW_ONE_TO_NINE_in_octave346); 
            ONE_TO_NINE28_tree = (Object)adaptor.create(ONE_TO_NINE28);
            adaptor.addChild(root_0, ONE_TO_NINE28_tree);


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "octave"

    public static class start_func_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "start_func"
    // AmFm.g:193:1: start_func : START '{' ( function )* '}' -> ^( START ( function )* ) ;
    public final AmFmParser.start_func_return start_func() throws RecognitionException {
        AmFmParser.start_func_return retval = new AmFmParser.start_func_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token START29=null;
        Token char_literal30=null;
        Token char_literal32=null;
        AmFmParser.function_return function31 = null;


        Object START29_tree=null;
        Object char_literal30_tree=null;
        Object char_literal32_tree=null;
        RewriteRuleTokenStream stream_START=new RewriteRuleTokenStream(adaptor,"token START");
        RewriteRuleTokenStream stream_30=new RewriteRuleTokenStream(adaptor,"token 30");
        RewriteRuleTokenStream stream_32=new RewriteRuleTokenStream(adaptor,"token 32");
        RewriteRuleSubtreeStream stream_function=new RewriteRuleSubtreeStream(adaptor,"rule function");
        try {
            // AmFm.g:193:11: ( START '{' ( function )* '}' -> ^( START ( function )* ) )
            // AmFm.g:193:13: START '{' ( function )* '}'
            {
            START29=(Token)match(input,START,FOLLOW_START_in_start_func354);  
            stream_START.add(START29);

            char_literal30=(Token)match(input,30,FOLLOW_30_in_start_func356);  
            stream_30.add(char_literal30);

            // AmFm.g:193:23: ( function )*
            loop11:
            do {
                int alt11=2;
                int LA11_0 = input.LA(1);

                if ( ((LA11_0>=PLAY && LA11_0<=SS_ALL)) ) {
                    alt11=1;
                }


                switch (alt11) {
            	case 1 :
            	    // AmFm.g:193:23: function
            	    {
            	    pushFollow(FOLLOW_function_in_start_func358);
            	    function31=function();

            	    state._fsp--;

            	    stream_function.add(function31.getTree());

            	    }
            	    break;

            	default :
            	    break loop11;
                }
            } while (true);

            char_literal32=(Token)match(input,32,FOLLOW_32_in_start_func361);  
            stream_32.add(char_literal32);



            // AST REWRITE
            // elements: START, function
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 193:37: -> ^( START ( function )* )
            {
                // AmFm.g:193:40: ^( START ( function )* )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_START.nextNode(), root_1);

                // AmFm.g:193:48: ( function )*
                while ( stream_function.hasNext() ) {
                    adaptor.addChild(root_1, stream_function.nextTree());

                }
                stream_function.reset();

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;
            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "start_func"

    public static class function_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "function"
    // AmFm.g:194:1: function : ( play | ss_func ) ';' ;
    public final AmFmParser.function_return function() throws RecognitionException {
        AmFmParser.function_return retval = new AmFmParser.function_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token char_literal35=null;
        AmFmParser.play_return play33 = null;

        AmFmParser.ss_func_return ss_func34 = null;


        Object char_literal35_tree=null;

        try {
            // AmFm.g:194:9: ( ( play | ss_func ) ';' )
            // AmFm.g:194:11: ( play | ss_func ) ';'
            {
            root_0 = (Object)adaptor.nil();

            // AmFm.g:194:11: ( play | ss_func )
            int alt12=2;
            int LA12_0 = input.LA(1);

            if ( (LA12_0==PLAY) ) {
                alt12=1;
            }
            else if ( ((LA12_0>=SS_PITCH && LA12_0<=SS_ALL)) ) {
                alt12=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 12, 0, input);

                throw nvae;
            }
            switch (alt12) {
                case 1 :
                    // AmFm.g:194:12: play
                    {
                    pushFollow(FOLLOW_play_in_function377);
                    play33=play();

                    state._fsp--;

                    adaptor.addChild(root_0, play33.getTree());

                    }
                    break;
                case 2 :
                    // AmFm.g:194:19: ss_func
                    {
                    pushFollow(FOLLOW_ss_func_in_function381);
                    ss_func34=ss_func();

                    state._fsp--;

                    adaptor.addChild(root_0, ss_func34.getTree());

                    }
                    break;

            }

            char_literal35=(Token)match(input,31,FOLLOW_31_in_function384); 
             
                    numOfFunctionCalls++; 
                  

            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "function"

    public static class play_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "play"
    // AmFm.g:198:1: play : PLAY '(' func_params[$PLAY.text] ')' -> ^( PLAY func_params ) ;
    public final AmFmParser.play_return play() throws RecognitionException {
        AmFmParser.play_return retval = new AmFmParser.play_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token PLAY36=null;
        Token char_literal37=null;
        Token char_literal39=null;
        AmFmParser.func_params_return func_params38 = null;


        Object PLAY36_tree=null;
        Object char_literal37_tree=null;
        Object char_literal39_tree=null;
        RewriteRuleTokenStream stream_35=new RewriteRuleTokenStream(adaptor,"token 35");
        RewriteRuleTokenStream stream_36=new RewriteRuleTokenStream(adaptor,"token 36");
        RewriteRuleTokenStream stream_PLAY=new RewriteRuleTokenStream(adaptor,"token PLAY");
        RewriteRuleSubtreeStream stream_func_params=new RewriteRuleSubtreeStream(adaptor,"rule func_params");
        try {
            // AmFm.g:198:5: ( PLAY '(' func_params[$PLAY.text] ')' -> ^( PLAY func_params ) )
            // AmFm.g:198:7: PLAY '(' func_params[$PLAY.text] ')'
            {
            PLAY36=(Token)match(input,PLAY,FOLLOW_PLAY_in_play399);  
            stream_PLAY.add(PLAY36);

            char_literal37=(Token)match(input,35,FOLLOW_35_in_play401);  
            stream_35.add(char_literal37);

            pushFollow(FOLLOW_func_params_in_play403);
            func_params38=func_params((PLAY36!=null?PLAY36.getText():null));

            state._fsp--;

            stream_func_params.add(func_params38.getTree());
            char_literal39=(Token)match(input,36,FOLLOW_36_in_play406);  
            stream_36.add(char_literal39);



            // AST REWRITE
            // elements: func_params, PLAY
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 198:44: -> ^( PLAY func_params )
            {
                // AmFm.g:198:47: ^( PLAY func_params )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_PLAY.nextNode(), root_1);

                adaptor.addChild(root_1, stream_func_params.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;
            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "play"

    public static class ss_func_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "ss_func"
    // AmFm.g:199:1: ss_func : ss_func_name '(' ss_func_params[$ss_func_name.text] ')' -> ^( ss_func_name ss_func_params ) ;
    public final AmFmParser.ss_func_return ss_func() throws RecognitionException {
        AmFmParser.ss_func_return retval = new AmFmParser.ss_func_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token char_literal41=null;
        Token char_literal43=null;
        AmFmParser.ss_func_name_return ss_func_name40 = null;

        AmFmParser.ss_func_params_return ss_func_params42 = null;


        Object char_literal41_tree=null;
        Object char_literal43_tree=null;
        RewriteRuleTokenStream stream_35=new RewriteRuleTokenStream(adaptor,"token 35");
        RewriteRuleTokenStream stream_36=new RewriteRuleTokenStream(adaptor,"token 36");
        RewriteRuleSubtreeStream stream_ss_func_name=new RewriteRuleSubtreeStream(adaptor,"rule ss_func_name");
        RewriteRuleSubtreeStream stream_ss_func_params=new RewriteRuleSubtreeStream(adaptor,"rule ss_func_params");
        try {
            // AmFm.g:199:8: ( ss_func_name '(' ss_func_params[$ss_func_name.text] ')' -> ^( ss_func_name ss_func_params ) )
            // AmFm.g:199:10: ss_func_name '(' ss_func_params[$ss_func_name.text] ')'
            {
            pushFollow(FOLLOW_ss_func_name_in_ss_func420);
            ss_func_name40=ss_func_name();

            state._fsp--;

            stream_ss_func_name.add(ss_func_name40.getTree());
            char_literal41=(Token)match(input,35,FOLLOW_35_in_ss_func422);  
            stream_35.add(char_literal41);

            pushFollow(FOLLOW_ss_func_params_in_ss_func424);
            ss_func_params42=ss_func_params((ss_func_name40!=null?input.toString(ss_func_name40.start,ss_func_name40.stop):null));

            state._fsp--;

            stream_ss_func_params.add(ss_func_params42.getTree());
            char_literal43=(Token)match(input,36,FOLLOW_36_in_ss_func427);  
            stream_36.add(char_literal43);



            // AST REWRITE
            // elements: ss_func_name, ss_func_params
            // token labels: 
            // rule labels: retval
            // token list labels: 
            // rule list labels: 
            // wildcard labels: 
            retval.tree = root_0;
            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.tree:null);

            root_0 = (Object)adaptor.nil();
            // 199:66: -> ^( ss_func_name ss_func_params )
            {
                // AmFm.g:199:69: ^( ss_func_name ss_func_params )
                {
                Object root_1 = (Object)adaptor.nil();
                root_1 = (Object)adaptor.becomeRoot(stream_ss_func_name.nextNode(), root_1);

                adaptor.addChild(root_1, stream_ss_func_params.nextTree());

                adaptor.addChild(root_0, root_1);
                }

            }

            retval.tree = root_0;
            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "ss_func"

    public static class ss_func_name_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "ss_func_name"
    // AmFm.g:200:1: ss_func_name : ( SS_PITCH | SS_VOLUME | SS_RHYTHM | SS_PITCH_VOLUME | SS_PITCH_RHYTHM | SS_RHYTHM_VOLUME | SS_ALL ) ;
    public final AmFmParser.ss_func_name_return ss_func_name() throws RecognitionException {
        AmFmParser.ss_func_name_return retval = new AmFmParser.ss_func_name_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token set44=null;

        Object set44_tree=null;

        try {
            // AmFm.g:200:13: ( ( SS_PITCH | SS_VOLUME | SS_RHYTHM | SS_PITCH_VOLUME | SS_PITCH_RHYTHM | SS_RHYTHM_VOLUME | SS_ALL ) )
            // AmFm.g:200:15: ( SS_PITCH | SS_VOLUME | SS_RHYTHM | SS_PITCH_VOLUME | SS_PITCH_RHYTHM | SS_RHYTHM_VOLUME | SS_ALL )
            {
            root_0 = (Object)adaptor.nil();

            set44=(Token)input.LT(1);
            if ( (input.LA(1)>=SS_PITCH && input.LA(1)<=SS_ALL) ) {
                input.consume();
                adaptor.addChild(root_0, (Object)adaptor.create(set44));
                state.errorRecovery=false;
            }
            else {
                MismatchedSetException mse = new MismatchedSetException(null,input);
                throw mse;
            }


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "ss_func_name"

    public static class ss_func_params_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "ss_func_params"
    // AmFm.g:201:1: ss_func_params[String func_name] : func_params[$func_name] ',' BOOLEAN ;
    public final AmFmParser.ss_func_params_return ss_func_params(String func_name) throws RecognitionException {
        AmFmParser.ss_func_params_return retval = new AmFmParser.ss_func_params_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token char_literal46=null;
        Token BOOLEAN47=null;
        AmFmParser.func_params_return func_params45 = null;


        Object char_literal46_tree=null;
        Object BOOLEAN47_tree=null;

        try {
            // AmFm.g:201:33: ( func_params[$func_name] ',' BOOLEAN )
            // AmFm.g:201:35: func_params[$func_name] ',' BOOLEAN
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_func_params_in_ss_func_params474);
            func_params45=func_params(func_name);

            state._fsp--;

            adaptor.addChild(root_0, func_params45.getTree());
            char_literal46=(Token)match(input,33,FOLLOW_33_in_ss_func_params477); 
            BOOLEAN47=(Token)match(input,BOOLEAN,FOLLOW_BOOLEAN_in_ss_func_params480); 
            BOOLEAN47_tree = (Object)adaptor.create(BOOLEAN47);
            adaptor.addChild(root_0, BOOLEAN47_tree);


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "ss_func_params"

    public static class func_params_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "func_params"
    // AmFm.g:202:1: func_params[String func_name] : ID ',' start_bar ',' num_of_bars ;
    public final AmFmParser.func_params_return func_params(String func_name) throws RecognitionException {
        AmFmParser.func_params_return retval = new AmFmParser.func_params_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token ID48=null;
        Token char_literal49=null;
        Token char_literal51=null;
        AmFmParser.start_bar_return start_bar50 = null;

        AmFmParser.num_of_bars_return num_of_bars52 = null;


        Object ID48_tree=null;
        Object char_literal49_tree=null;
        Object char_literal51_tree=null;

        try {
            // AmFm.g:202:30: ( ID ',' start_bar ',' num_of_bars )
            // AmFm.g:202:32: ID ',' start_bar ',' num_of_bars
            {
            root_0 = (Object)adaptor.nil();

            ID48=(Token)match(input,ID,FOLLOW_ID_in_func_params487); 
            ID48_tree = (Object)adaptor.create(ID48);
            adaptor.addChild(root_0, ID48_tree);

            char_literal49=(Token)match(input,33,FOLLOW_33_in_func_params489); 
            pushFollow(FOLLOW_start_bar_in_func_params492);
            start_bar50=start_bar();

            state._fsp--;

            adaptor.addChild(root_0, start_bar50.getTree());
            char_literal51=(Token)match(input,33,FOLLOW_33_in_func_params494); 
            pushFollow(FOLLOW_num_of_bars_in_func_params497);
            num_of_bars52=num_of_bars();

            state._fsp--;

            adaptor.addChild(root_0, num_of_bars52.getTree());
             
                          if (startedFromProgramRule) { // Do validation only if we parse a whole program
            	              // Check if seed was defind
            	              if (definedSeeds.get((ID48!=null?ID48.getText():null)) == null) {
            	                errorManager.addError(AmFmErrorCode.REFERRING_TO_UNDEFINED_SEED, (ID48!=null?ID48.getLine():0), (ID48!=null?ID48.getText():null), func_name);
            	              } else if(definedSeeds.get((ID48!=null?ID48.getText():null))) {
            	                errorManager.addError(AmFmErrorCode.REFERRING_TO_ALL_RESTS_SEED, (ID48!=null?ID48.getLine():0), (ID48!=null?ID48.getText():null), func_name); 
            	              } else { // put seed in the set of used seeds
            	                usedSeeds.add((ID48!=null?ID48.getText():null));
            	              }
            	              
                          }
                        

            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "func_params"

    public static class start_bar_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "start_bar"
    // AmFm.g:216:1: start_bar : number ;
    public final AmFmParser.start_bar_return start_bar() throws RecognitionException {
        AmFmParser.start_bar_return retval = new AmFmParser.start_bar_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        AmFmParser.number_return number53 = null;



        try {
            // AmFm.g:216:10: ( number )
            // AmFm.g:216:12: number
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_number_in_start_bar519);
            number53=number();

            state._fsp--;

            adaptor.addChild(root_0, number53.getTree());

            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "start_bar"

    public static class num_of_bars_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "num_of_bars"
    // AmFm.g:217:1: num_of_bars : number ;
    public final AmFmParser.num_of_bars_return num_of_bars() throws RecognitionException {
        AmFmParser.num_of_bars_return retval = new AmFmParser.num_of_bars_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        AmFmParser.number_return number54 = null;



        try {
            // AmFm.g:217:12: ( number )
            // AmFm.g:217:14: number
            {
            root_0 = (Object)adaptor.nil();

            pushFollow(FOLLOW_number_in_num_of_bars526);
            number54=number();

            state._fsp--;

            adaptor.addChild(root_0, number54.getTree());

            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "num_of_bars"

    public static class number_return extends ParserRuleReturnScope {
        Object tree;
        public Object getTree() { return tree; }
    };

    // $ANTLR start "number"
    // AmFm.g:218:1: number : ( ONE_TO_NINE | TEN_AND_UP );
    public final AmFmParser.number_return number() throws RecognitionException {
        AmFmParser.number_return retval = new AmFmParser.number_return();
        retval.start = input.LT(1);

        Object root_0 = null;

        Token set55=null;

        Object set55_tree=null;

        try {
            // AmFm.g:218:9: ( ONE_TO_NINE | TEN_AND_UP )
            // AmFm.g:
            {
            root_0 = (Object)adaptor.nil();

            set55=(Token)input.LT(1);
            if ( input.LA(1)==ONE_TO_NINE||input.LA(1)==TEN_AND_UP ) {
                input.consume();
                adaptor.addChild(root_0, (Object)adaptor.create(set55));
                state.errorRecovery=false;
            }
            else {
                MismatchedSetException mse = new MismatchedSetException(null,input);
                throw mse;
            }


            }

            retval.stop = input.LT(-1);

            retval.tree = (Object)adaptor.rulePostProcessing(root_0);
            adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
    	retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);

        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "number"

    // Delegated rules


 

    public static final BitSet FOLLOW_seed_in_program85 = new BitSet(new long[]{0x0000000020010000L});
    public static final BitSet FOLLOW_start_func_in_program88 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_29_in_seed130 = new BitSet(new long[]{0x0000000000000100L});
    public static final BitSet FOLLOW_ID_in_seed132 = new BitSet(new long[]{0x0000000040000000L});
    public static final BitSet FOLLOW_30_in_seed134 = new BitSet(new long[]{0x0000000000000200L});
    public static final BitSet FOLLOW_INSTRUMENT_in_seed136 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_31_in_seed138 = new BitSet(new long[]{0x0000000400002400L});
    public static final BitSet FOLLOW_note_unit_in_seed140 = new BitSet(new long[]{0x0000000500002400L});
    public static final BitSet FOLLOW_32_in_seed143 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_note_in_note_unit182 = new BitSet(new long[]{0x0000000280000000L});
    public static final BitSet FOLLOW_33_in_note_unit187 = new BitSet(new long[]{0x0000000004008800L});
    public static final BitSet FOLLOW_duration_in_note_unit189 = new BitSet(new long[]{0x0000000280000000L});
    public static final BitSet FOLLOW_33_in_note_unit193 = new BitSet(new long[]{0x0000000400001000L});
    public static final BitSet FOLLOW_volume_in_note_unit195 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_31_in_note_unit202 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_REST_in_note_unit260 = new BitSet(new long[]{0x0000000280000000L});
    public static final BitSet FOLLOW_33_in_note_unit264 = new BitSet(new long[]{0x0000000004008800L});
    public static final BitSet FOLLOW_duration_in_note_unit266 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_31_in_note_unit270 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_FRACTION_in_duration299 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_number_in_duration303 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_set_in_volume0 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_note_letter_in_note323 = new BitSet(new long[]{0x0000000000008002L});
    public static final BitSet FOLLOW_octave_in_note325 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_NOTELETTERS_WITH_ACCIDENTAL_MINUS_F_in_note_letter334 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_34_in_note_letter338 = new BitSet(new long[]{0x0000000000004002L});
    public static final BitSet FOLLOW_ACCIDENTAL_in_note_letter339 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ONE_TO_NINE_in_octave346 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_START_in_start_func354 = new BitSet(new long[]{0x0000000040000000L});
    public static final BitSet FOLLOW_30_in_start_func356 = new BitSet(new long[]{0x0000000101FE0000L});
    public static final BitSet FOLLOW_function_in_start_func358 = new BitSet(new long[]{0x0000000101FE0000L});
    public static final BitSet FOLLOW_32_in_start_func361 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_play_in_function377 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_ss_func_in_function381 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_31_in_function384 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_PLAY_in_play399 = new BitSet(new long[]{0x0000000800000000L});
    public static final BitSet FOLLOW_35_in_play401 = new BitSet(new long[]{0x0000000000000100L});
    public static final BitSet FOLLOW_func_params_in_play403 = new BitSet(new long[]{0x0000001000000000L});
    public static final BitSet FOLLOW_36_in_play406 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ss_func_name_in_ss_func420 = new BitSet(new long[]{0x0000000800000000L});
    public static final BitSet FOLLOW_35_in_ss_func422 = new BitSet(new long[]{0x0000000000000100L});
    public static final BitSet FOLLOW_ss_func_params_in_ss_func424 = new BitSet(new long[]{0x0000001000000000L});
    public static final BitSet FOLLOW_36_in_ss_func427 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_set_in_ss_func_name441 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_func_params_in_ss_func_params474 = new BitSet(new long[]{0x0000000200000000L});
    public static final BitSet FOLLOW_33_in_ss_func_params477 = new BitSet(new long[]{0x0000000002000000L});
    public static final BitSet FOLLOW_BOOLEAN_in_ss_func_params480 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ID_in_func_params487 = new BitSet(new long[]{0x0000000200000000L});
    public static final BitSet FOLLOW_33_in_func_params489 = new BitSet(new long[]{0x0000000004008800L});
    public static final BitSet FOLLOW_start_bar_in_func_params492 = new BitSet(new long[]{0x0000000200000000L});
    public static final BitSet FOLLOW_33_in_func_params494 = new BitSet(new long[]{0x0000000004008800L});
    public static final BitSet FOLLOW_num_of_bars_in_func_params497 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_number_in_start_bar519 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_number_in_num_of_bars526 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_set_in_number0 = new BitSet(new long[]{0x0000000000000002L});

}